const express = require('express');
const cors = require('cors');
const fs = require('fs');
const path = require('path');
const mime = require('mime-types');
const app = express();

// 允许跨域请求
app.use(cors());
app.use(express.static('public')); // 托管 public 目录
app.use(express.json()); // 解析 JSON 请求体


// 设置视频文件夹路径（示例：手机根目录的 Movies 文件夹）。如果是在本地运行，请去除掉`storage`前面的/。这里的路径只是为了模拟手机的文件系统，除非你想将此项目运行在你的电脑上。

const videoDir = '/storage/emulated/0/Movies';
// file-info文件是存储你自己添加的视频的信息，包括视频的名称、描述、url等的文件，再次部署时，可以不复制该文件，以免数据被覆盖
const jsonPath = '/storage/emulated/0/download/server/file-info.json';

let allMovies = [];
let fileInfo = {};


function readFileInfo() {
  return new Promise((resolve, reject) => {
    fs.readFile(jsonPath, 'utf8', (err, data) => {
      if (err) {
        console.error('读取文件失败:', err);
        return reject(err);
      }
      try {
        fileInfo = JSON.parse(data);
        return resolve(fileInfo);
      } catch (error) {
        console.error('解析 JSON 失败:', error);
        return reject(error);
      }
    })

  })
}

function writeFileInfo() {
  return new Promise((resolve, reject) => {
    fs.writeFile(jsonPath, JSON.stringify(fileInfo), 'utf8', (err) => {
      if (err) {
        console.error('写入文件失败:', err);
        return;
      }
      readFileInfo();
    });
  })
}

// 编辑文件信息接口
app.post('/api/edit', (req, res) => {
  const { url, name, desc } = req.body;
  if (!url || !name || !desc) {
    return res.status(400).json({ message: '参数错误' });
  }
  fileInfo[url] = { name, desc, url };
  writeFileInfo();
  res.json({ message: '修改成功' });
});


app.get('/api/info', (req, res) => {
  let url = req.query.v
  let item = allMovies.find(ele => ele.url == url)
  let info = fileInfo[encodeURIComponent(url)]
  if (info) {
    item.name = info.name
    item.desc = info.desc
  }
  res.json({code: 200, data: item})  
})



// 查询全部的视频文件，并将之存储到数组中，方便前端使用
function getAllMovies() {
  return new Promise((resolve, reject) => {
    fs.readdir(videoDir, {withFileTypes:true}, (err, files) => {
      if (err) {
        console.error('读取文件夹失败:', err);
        return reject(err);
      }
      allMovies = files
      .filter(file => file.isFile() && /\.(mp4|mkv|avi)$/i.test(file.name))
      .map(file => {
        return {
          name: file.name,
          url: `/video/${encodeURIComponent(file.name)}`
        }
      }
      );
      console.log('视频文件加载完成', allMovies.length);
      return resolve(allMovies);
    })
  })
}

// 获取文件列表接口
app.get('/api/files', (req, res) => {
  const { size = 10, page = 1 } = req.query;
  const start = (page - 1) * size;
  const end = start + size * 1;
  const videoList = allMovies.slice(start, end);
  // 为每个视频添加文件信息
  videoList.forEach(video => {
    let key = encodeURIComponent(video.url)
    if (fileInfo[key]) {
      video.name = fileInfo[key].name;
      video.desc = fileInfo[key].desc;
    }
    return video;

  })

  res.json({ total: allMovies.length, list: videoList });
});

app.get('/api/fresh', async (req, res) => {
  await readFileInfo();
  await getAllMovies();
  res.json({ code: 200, message: '刷新成功' });
})

// 视频流式传输接口（支持断点续传）
app.get('/video/:filename', (req, res) => {
  const filePath = path.join(videoDir, decodeURIComponent(req.params.filename));
  const mimeType = mime.lookup(filePath) || 'video/mp4'; // 默认 MP4 类型

  // 检查文件是否存在
  fs.stat(filePath, (err, stats) => {
    if (err) return res.status(404).send('文件未找到');

    // 处理范围请求（Range Headers）
    const range = req.headers.range;
    if (range) {
      const parts = range.replace(/bytes=/, '').split('-');
      const start = parseInt(parts[0], 10);
      const end = parts[1] ? parseInt(parts[1], 10) : stats.size - 1;
      const chunkSize = end - start + 1;

      res.writeHead(206, {
        'Content-Range': `bytes ${start}-${end}/${stats.size}`,
        'Accept-Ranges': 'bytes',
        'Content-Length': chunkSize,
        'Content-Type': mimeType
      });

      // 创建可读流并传输指定范围的数据
      const stream = fs.createReadStream(filePath, { start, end });
      stream.pipe(res);
    } else {
      // 无范围请求时传输整个文件
      res.writeHead(200, {
        'Content-Length': stats.size,
        'Content-Type': mimeType
      });
      fs.createReadStream(filePath).pipe(res);
    }
  });
});

// 启动服务器
const PORT = 3000;
app.listen(PORT, async () => {
  await readFileInfo();
  await getAllMovies();

  console.log(`服务器运行在 http://localhost:${PORT}`);
});